/**
 * RTCPage 使用rtc内存缓存文本内容
 */
#ifndef __RTC_PAGE_H__
#define __RTC_PAGE_H__
#include <Arduino.h>

/*
支持两种索引文件：
1、阅读索引*.pgx，顺序存储每个页面的偏移量，每个记录占用4个字节，且头两个字节被复用为上次阅读页号 
2、词条索引*.tmx，顺序存储词条索引，索引格式为PAGE_DATA，每个记录占用16个字节
使用一个番茄钟记录
tomato.dat 顺序记录（未实现）
年月日,{[时间,时长],...},数量
*/

// 缓存页数(墨水屏每页可显示19行14列汉字，将占用19*14*3个字节)
#define MAX_RTC_PAGE 8
// 向后预读页数
#define PRE_UP_PAGE 2
// 向前预读页数
#define PRE_DN_PAGE 6
// 用于缓存文本的字节数
#define MAX_RTC_BUFFER 7432
// 最大文件名长度
#define MAX_NAME_LENGTH 56

extern char rtcName[MAX_NAME_LENGTH];
extern int8_t rtcPgIdx;

// 页面缓存
typedef struct _page_data
{
	int16_t no;
	int16_t level;
	long nextMinute;
	union
	{
		char *title;
		long titleOffset;
	};
	union
	{
		char *content;
		long contentOffset;
	};
} PAGE_DATA;

/**
 * @brief 取视图类型
*/
char getViewType();

/**
 * @brief 设置视图类型
*/
void setViewType(char type);

/**
 * @brief 保存进度
*/
void saveProcess();

/**
 * @brief 文件 lastRead.cfg 保存上次阅读类型和文件名
 * @param type 阅读类型
 * @param fName 文件名称
*/
void saveLastRead(uint8_t type, char *fName);

/**
 * @brief 读取上次阅读类型和文件名
 * @param fName 用于保存读得的文件名
 * @return 阅读类型， 0表示没有
*/
uint8_t readLastRead(char *fName);

/**
 * @brief 使用RTC内存缓存页面文本，以便唤醒后立即取用
 */
class RTCPage
{
public:
	/**
	 * @brief 构建目录内容
	 */
	RTCPage(bool init);

	/**
	 * @brief 构建文本内容
	 * @param fileName 相关文件名称 长度不能超过MAX_NAME_LENGTH字节
	 */
	RTCPage(bool init, char *fileName);

	/**
	 * @brief 缓存文本内容，若缓存已满，旧内容将被清除
	 * @param buf 要缓存的文本
	 * @param side 0 在尾部插入, 1 按页号顺序插入
	 * @return true 缓存成功，否则失败
	 */
	bool append(PAGE_DATA *buf, int side);

    /**
     * @brief 检查或设置是否需要预读入
     * @return true 需要预读并已设置预读参数
    */
    void checkPreLoad();

	/**
	 * @brief 按页号读入内容
	 * @param pgNo 开始页号
	 * @param pgCount 读入页数
	 */
	bool load(int pgNo, int pgCount);

	/**
	 * 移动页指针step步进页指针 side
	 * @param side 步进一页，-1：退后，1：向前
	 * @return 成功则返回真
	 */
	bool step(int side);

    /**
     * @brief 内容标题
    */
    char *readCtxInfo();

	/**
	 * @brief 取当前词条标题
	 * @return 词条标题
	 */
	char *readTitle();

	/**
	 * @brief 取当前文本内容
	 * @return 文本内容
	 */
	char *readContent();

	/**
	 * @brief 取焦点行
	 * @return 焦点行号
	 */
	int getFocusLine();

	/**
	 * @brief 复制焦点行字符串
	 * @param str 用于保存复制过来的字符串
	 * @return 成功则返回true
	*/
	bool copyFocusString(char *str);
protected:
	/**
	 * 初始化页面内容
	*/
	void initPage();

	/**
	 * @brief 按页号读入目录内容
	 * @param pgNo 开始页号
	 * @param pgCount 读入页数
	 */
	bool loadDir(int pgNo, int pgCount);

	/**
	 * @brief 按页号读入文本内容
	 * @param pgNo 开始页号
	 * @param pgCount 读入页数
	 */
	bool loadFile(int pgNo, int pgCount);

	/**
	 * @brief 读入多页词条
	 * @param pgCount 读入页数
	 */
	bool loadTerm(int pgCount);

	/**
	 * @brief 增加词条索引
	 * @param int pgNo 新增起始页号
	 * @param long pgOffset 新增文本偏移量
	*/
	bool appendTerm(int pgNo, long pgOffset);

    int8_t readSide = 0;
};

#endif